/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.wanhai.itm.util;

import com.wanhai.itm.converter.DateConverter;
import com.wanhai.itm.converter.SelectedItemConverter;
import com.wanhai.itm.liveListModel.LiveListModel;
import com.wanhai.itm.validator.NoEmptyValidator;
import com.wanhai.util.UserBean;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpSession;
import org.apache.commons.beanutils.BeanUtils;
import org.zkoss.bind.BindUtils;
import org.zkoss.bind.Converter;
import org.zkoss.bind.Validator;
import org.zkoss.bind.annotation.BindingParam;
import org.zkoss.bind.annotation.Command;
import org.zkoss.bind.annotation.ContextParam;
import org.zkoss.bind.annotation.ContextType;
import org.zkoss.bind.annotation.Default;
import org.zkoss.bind.annotation.NotifyChange;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.Executions;
import org.zkoss.zk.ui.event.CheckEvent;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.http.SimpleSession;
import org.zkoss.zk.ui.select.annotation.Wire;
import org.zkoss.zk.ui.util.Clients;
import org.zkoss.zul.Include;
import org.zkoss.zul.Listheader;
import org.zkoss.zul.Messagebox;
import org.zkoss.zul.Textbox;
import org.zkoss.zul.Window;

/**
 *
 * @author m2434
 */
public abstract class WD_DefaultVM<T> {
    private Validator noEmptyValidator = new NoEmptyValidator();
    private Converter dateConveter = new DateConverter();
    private Converter selectedItemConveter = new SelectedItemConverter();
    
    private Class<T> voClass;
    private T selected;
    private int selectedIndex;
    private List<T> selecteds;
    private LiveListModel<T> items;
    private T cond;//query condition
    protected VoDataService<T> voService = new VoDataService<T>();
    
    private String actionFlag;
    private String orderBy = "";
    
    protected SimpleSession s = (SimpleSession) Executions.getCurrent().getDesktop().getSession();
    protected HttpSession session = (HttpSession) s.getNativeSession();
    protected UserBean user = (UserBean) session.getAttribute("LOGIN_USER");
    
    ///<editor-fold defaultstate="collapsed" desc="binding UI component">
    @Wire("#inc1")
    protected Include inc1;
    //</editor-fold>
    
    public WD_DefaultVM(Class<T> voClass){
        this.voClass = voClass;
        clearCond();
    }
    
    @Command
    @NotifyChange("items")
    public void query(){
        try{
            voService.setOrderBy(this.getOrderBy());
            this.setItems(voService.queryLive(cond));
            
        }catch(Exception e){
            e.printStackTrace();
        }
    }
    
    @Command
    @NotifyChange("items")
    public void onSort(@BindingParam("column") Listheader col){
        String ascDesc = col.getSortDirection().indexOf("asc") >=0? "asc" : "desc";
            this.setOrderBy(col.getValue().toString() + " " + ascDesc);
            this.query();
    }
    
    @Command
    @NotifyChange("cond")
    public void clearCond(){
        try{
            this.setCond(voClass.newInstance());
        }catch(Exception e){
            
        }
    }

    @Command
    @NotifyChange({"selected","actionFlag"})
    public void preInsert() throws Exception{
        this.setActionFlag("insert");
        
        this.setSelected(voClass.newInstance());
        
        ((Window)inc1.getFellow("operatorWin")).doModal();
    }
    
    @Command
    @NotifyChange({"items"})
    public void insert() throws Exception{
        
        BeanUtils.setProperty(selected, "ENTRY_OFFICE", user.getOfficeCode());
        BeanUtils.setProperty(selected, "ENTRY_USER", user.getUserCode());
        voService.insert(selected);
        
        this.setCond(this.getSelected());
        this.query();
        this.clearCond();
        inc1.getFellow("operatorWin").setVisible(false);
        
        Clients.showNotification("insert complete","info",null,"top_right",2000);
    }
    
    @Command
    @NotifyChange({"selected","actionFlag","selectedIndex"})
    public void preUpdate(@BindingParam("selected") T selected,@BindingParam("selectedIndex") int selectedIndex) throws Exception{
        
        this.setActionFlag("update");
        this.setSelectedIndex(selectedIndex);
        this.setSelected(selected);
        
        ((Window)inc1.getFellow("operatorWin")).doModal();
    }
    
    @Command
    @NotifyChange("items")
    public void update() throws Exception{
        voService.update(selected);
        
        inc1.getFellow("operatorWin").setVisible(false);
        
        Clients.showNotification("update complete","info",null,"top_right",2000);
    }
    
    @Command
//    @NotifyChange("items")
    public void delete(@BindingParam("selected") T selected) throws Exception{
        this.setSelected(selected);
        
        Messagebox.show("Are you sure to delete?", "Confirm Dialog", Messagebox.OK | Messagebox.CANCEL, Messagebox.QUESTION, new org.zkoss.zk.ui.event.EventListener() {
            public void onEvent(Event evt) throws InterruptedException, Exception {
                if (evt.getName().equals("onOK")) {
                    voService.delete(getSelected());
                    query();
                    Clients.showNotification("delete complete","info",null,"top_right",2000);
                } 
                
                BindUtils.postNotifyChange(null,null,WD_DefaultVM.this,"items");
            }
        });
        
    }
    
    @Command
//    @NotifyChange("items")
    public void multiDelete() throws Exception{
        System.out.println("this.getSelecteds().size = "+ this.getSelecteds().size());
        if(this.getSelecteds().isEmpty()){
            Clients.showNotification("please selected one item","error",null,"top_right",2000);
        }else{
            Messagebox.show("Are you sure to delete?", "Confirm Dialog", Messagebox.OK | Messagebox.CANCEL, Messagebox.QUESTION, new org.zkoss.zk.ui.event.EventListener() {
                public void onEvent(Event evt) throws InterruptedException, Exception {
                    if (evt.getName().equals("onOK")) {
                        for(T vo : getSelecteds()){
                            voService.delete(vo);
                        }
                        query();
                        Clients.showNotification("delete complete","info",null,"top_right",2000);
                    } 
                    
                    getSelecteds().clear();
                    BindUtils.postNotifyChange(null,null,WD_DefaultVM.this,"items");
                }
            });
        }
    }
    
    @Command
    @NotifyChange("items")
    public void selectAll(@ContextParam(ContextType.TRIGGER_EVENT) CheckEvent e){
        LiveListModel lml = this.getItems();
        
        if (e.isChecked()){
            this.setSelecteds(lml.getPageResult());
        }else{
            this.setSelecteds(null);
        }
    }
    
    @Command
    @NotifyChange({"selected","selectedIndex"})
    public void itemsReview(@BindingParam("direction") String direction) throws Exception{
        LiveListModel lml = this.getItems();
        int point = 0;
        
        if(direction.equals("prev")){
            point = this.getSelectedIndex()-1;
            
            if(point % lml.getPageSize() == (lml.getPageSize()-1)){
                lml.getElementAt(point);
                this.setItems(lml);
            }
        }else if(direction.equals("next")){
            point = this.getSelectedIndex()+1;
            
            if(point % lml.getPageSize() == 0){
                lml.getElementAt(point);
                this.setItems(lml);
            }
        }
        
        if(point <= lml.getSize()-1 && point >= 0){
            this.setSelected((T) lml.getPageResult().get(point % lml.getPageSize()));
//            this.preUpdate(point);
            this.setSelectedIndex(point);
        }
    }
    
    @Command
    public void showLov(@ContextParam(ContextType.VIEW) Component view,@BindingParam("callMethod") String callMethod
                                    , @BindingParam("lovName") String lovName ,@BindingParam("isMultiple") @Default("false") String isMultiple) throws Exception{
        Map args = new HashMap();
        args.put("callMethod", callMethod);
        args.put("lovName", lovName);
        args.put("isMultiple", isMultiple);
        
        Window popupWin = (Window)Executions.createComponents("../lov/lov.zul", view, args);
        popupWin.doModal();
    }
    
    //<editor-fold defaultstate="collapsed" desc="getter, setter">
    public Validator getNoEmptyValidator(){
        return noEmptyValidator;
    }
    
    public Converter getDateConveter() {
        return dateConveter;
    }
    
    public Converter getSelectedItemConveter() {
        return selectedItemConveter;
    }
    
    public void setSelectedItemConveter(Converter selectedItemConveter) {
        this.selectedItemConveter = selectedItemConveter;
    }
    
    public String getActionFlag() {
        return actionFlag;
    }
    
    public void setActionFlag(String actionFlag) {
        this.actionFlag = actionFlag;
    }
    
    public T getCond() {
        return cond;
    }
    
    public void setCond(T cond) {
        this.cond = cond;
    }
    
    public T getSelected() {
        return selected;
    }
    
    public void setSelected(T selected) {
        this.selected = selected;
    }

    public int getSelectedIndex() {
        return selectedIndex;
    }

    public void setSelectedIndex(int selectedIndex) {
        this.selectedIndex = selectedIndex;
    }
    
    public List<T> getSelecteds() {
        return selecteds;
    }
    
    public void setSelecteds(List<T> selecteds) {
        this.selecteds = selecteds;
    }
    
    public LiveListModel<T> getItems() {
        return items;
    }
    
    public void setItems(LiveListModel<T> items) {
        this.items = items;
    }
    
    public String getOrderBy() {
        return orderBy;
    }

    public void setOrderBy(String orderBy) {
        this.orderBy = orderBy;
    }
//</editor-fold>

    
}
